package sprites
{
	import UIComponent.LineSkeleton;
	import UIComponent.PointSprite;
	
	import flash.events.MouseEvent;
	
	import mx.collections.ArrayList;
	import mx.controls.Button;
	import mx.events.PropertyChangeEvent;
	
	import skeletons.ConclusionSkeleton;
	import skeletons.DKRelationSkeleton;
	import skeletons.DataSourceSkeleton;
	import skeletons.KConRelationSkeleton;
	import skeletons.KnowledgeSkeleton;

	public class KnowledgeSprite extends PointSprite
	{
		//component
		private var highlight:Button;
		private var fromDisconnect:Button;
		private var deriveDisconnect:Button;
		
		//status
		private var showFromDisconnect:Boolean = false;
		private var fromDisconnectRelation:DKRelationSkeleton;
		private var showDeriveDisconnect:Boolean = false;
		private var deriveDisconnectRelation:KConRelationSkeleton;
		
		public function KnowledgeSprite(_knowledge:KnowledgeSkeleton, _canvas:MyCanvas)
		{
			super(_knowledge,_canvas);
			
			//component
			highlight=new Button();
			this.addChild(highlight);
			highlight.label="k";
			highlight.x = DEFAULT_MINI_WIDTH - MARGIN_WIDTH*3 - CONVERT_WIDTH - REMOVE_WIDTH - BUTTON_WIDTH;
			highlight.y = MARGIN_HEIGHT;
			highlight.width= BUTTON_WIDTH;
			highlight.height = DEFAULT_MINI_HEIGHT - MARGIN_HEIGHT*2;
			highlight.addEventListener(MouseEvent.CLICK,onTraceBoth);
			
			deriveDisconnect=new Button();
			this.addChild(deriveDisconnect);
			deriveDisconnect.label="";
			deriveDisconnect.x= getWidth();
			deriveDisconnect.width= BUTTON_WIDTH/2;
			deriveDisconnect.height= DEFAULT_MINI_HEIGHT - MARGIN_HEIGHT*2;
			deriveDisconnect.y= MARGIN_HEIGHT;
			deriveDisconnect.addEventListener(MouseEvent.CLICK,onRemoveKConRelation);
			deriveDisconnectRelation=null;
			deriveDisconnect.visible=false;
			
			fromDisconnect=new Button();
			this.addChild(fromDisconnect);
			fromDisconnect.label="";
			fromDisconnect.x=-1*BUTTON_WIDTH/2;
			fromDisconnect.width= BUTTON_WIDTH/2;
			fromDisconnect.height= DEFAULT_MINI_HEIGHT - MARGIN_HEIGHT*2;
			fromDisconnect.y= MARGIN_HEIGHT;
			fromDisconnect.addEventListener(MouseEvent.CLICK,onRemoveDKRelation);
			fromDisconnectRelation=null;
			fromDisconnect.visible=false;
			
			
			this.addEventListener(MouseEvent.MOUSE_DOWN,onMouseDown);
			this.addEventListener(MouseEvent.MOUSE_UP,onMouseUp);
			this.addEventListener(MouseEvent.DOUBLE_CLICK,onTraceBoth);
			
			
			
		}
	
		override protected function onSelected(evt:MouseEvent):void
		{
			if(canvas.getSelectedKnow()==this)
			{
				canvas.setSelectedKnow(null);
				this.selected=false;
				this.invalidateDisplayList();
			}
			else
			{
				if(canvas.getSelectedKnow()==null)
				{
					//do nothing
				}
				else
				{
					canvas.getSelectedKnow().selected=false;
					canvas.getSelectedKnow().invalidateDisplayList();
				}
				canvas.setSelectedKnow(this);
				this.selected=true;
				this.invalidateDisplayList();
			}
		}
		
		override public function remove():void
		{
			canvas.removeChild(this);
		}
		
		override protected function onRemove(evt:MouseEvent):void
		{
			super.onRemove(evt);
			canvas.curProject.removeKnowledge((KnowledgeSkeleton)(this.getSkeleton()));
		}
		
		protected function onMouseDown(evt:MouseEvent):void
		{
			canvas.setMouseDownObject(this);
			
		}
		
		protected function onMouseUp(evt:MouseEvent):void
		{
			var mouseDownObject:Object=canvas.getMouseDownObject();
			
			if(mouseDownObject==null)
			{
				return;
			}
			
			if(mouseDownObject is DataSourceSprite)
			{	
				//add DK relation
						
				var _dataSource:DataSourceSkeleton = (DataSourceSkeleton)(((DataSourceSprite)(mouseDownObject)).getSkeleton());
				var _knowledge:KnowledgeSkeleton= (KnowledgeSkeleton)(this.getSkeleton());
				
				canvas.curProject.sendAddDKRelation(_dataSource.getDID(), _knowledge.getKID(), canvas.getSelectedLinkType());
//				var tempDK:DKRelationSkeleton = canvas.curProject.addDKRelation(_dataSource,_knowledge,canvas.getSelectedLinkType());
//				canvas.addDKRelationAssist(_dataSource,_knowledge,tempDK);
			}
			else if(mouseDownObject is ConclustionSprite)
			{
				//add KCon Relation
				
				var _knowledge:KnowledgeSkeleton = (KnowledgeSkeleton)(this.getSkeleton());
				var _conclusion:ConclusionSkeleton = (ConclusionSkeleton)(((ConclustionSprite)(mouseDownObject)).getSkeleton());
				
				canvas.curProject.sendKConRelation( _knowledge.getKID(), _conclusion.getConID(), canvas.getSelectedLinkType());
			}
		}
		
		public function traceDerive(_isSelected:Boolean):void
		{
			setHighlight(_isSelected);
			this.invalidateDisplayList();
			var KConList:ArrayList = (KnowledgeSkeleton)(this.getSkeleton()).getKConList();
			if(KConList==null)
			{
				return;
			}
			var i:Number=0;
			for(i=0; i<KConList.length; i++)
			{
				var KCon:KConRelationSkeleton = (KConRelationSkeleton)(KConList.getItemAt(i));
				KCon.getSprite().setSelected(_isSelected);
				
				KCon.getToPointSkeleton().getSprite().setHighlight(_isSelected);
				KCon.getToPointSkeleton().getSprite().invalidateDisplayList();
				
				if(canvas.getTrackingObject() is KnowledgeSprite) //make sure not cascade
				{
					(ConclustionSprite)(KCon.getToPointSkeleton().getSprite()).showFromConnect(KCon,_isSelected);
				}
			}
			
		}
		
		public function traceFrom(_isSelected:Boolean):void
		{
			setHighlight(_isSelected);
			this.invalidateDisplayList();
			var DKList:ArrayList = (KnowledgeSkeleton)(this.getSkeleton()).getDKList();
			if(DKList==null)
			{
				return;
			}
			var i:Number=0;
			for(i=0; i<DKList.length; i++)
			{
				var DK:DKRelationSkeleton = (DKRelationSkeleton)(DKList.getItemAt(i));
				DK.getSprite().setSelected(_isSelected);
				
				//to be continued
				DK.getFromPointSkeleton().getSprite().setHighlight(_isSelected);
				DK.getFromPointSkeleton().getSprite().invalidateDisplayList();
				
				if(canvas.getTrackingObject() is KnowledgeSprite)	//make sure not cascade
				{
					(DataSourceSprite)(DK.getFromPointSkeleton().getSprite()).showDeriveConnect(DK,_isSelected);
				}
			}
			
		}
		
		protected function onTraceBoth(evt:MouseEvent):void
		{
			onSetTrace();
//			var tracingObject:Object = canvas.getTrackingObject();
//			if(tracingObject==null)
//			{
//				canvas.setTrackingObject(this);
//				traceDerive(true);
//				traceFrom(true);	
//			}
//			else
//			{
//				if(tracingObject is DataSourceSprite)
//				{
//					var tracingData:DataSourceSprite = (DataSourceSprite)(tracingObject);
//					tracingData.traceDerive(false);
//					
//					canvas.setTrackingObject(this);
//					traceDerive(true);
//					traceFrom(true);		
//				}
//				else if(tracingObject is KnowledgeSprite)
//				{
//					var tracingKnowledge:KnowledgeSprite = (KnowledgeSprite)(tracingObject);
//					
//					if(tracingKnowledge == this)
//					{
//						traceDerive(false);
//						traceFrom(false);
//						canvas.setTrackingObject(null);
//						
//					}
//					else
//					{
//						tracingKnowledge.traceDerive(false);
//						tracingKnowledge.traceFrom(false);
//					
//						canvas.setTrackingObject(this);
//						traceDerive(true);
//						traceFrom(true);
//						
//					}
//				}
//				else if(tracingObject is ConclustionSprite)
//				{
//					//to be continued
//					var tracingCon:ConclustionSprite = (ConclustionSprite)(tracingObject);
//					tracingCon.traceFrom(false);
//					
//					canvas.setTrackingObject(this);
//					traceDerive(true);
//					traceFrom(true);
//					
//				}
//			}
			this.canvas.invalidateDisplayList();
		}
		
		public function showFromConnect(_DKRelation:DKRelationSkeleton, _isShow:Boolean):void
		{
			if(_isShow == true)
			{
				fromDisconnect=new Button();
				this.addChild(fromDisconnect);
				fromDisconnect.label="";
				fromDisconnect.x=-1*BUTTON_WIDTH/2;
				fromDisconnect.width= BUTTON_WIDTH/2;
				fromDisconnect.height= DEFAULT_MINI_HEIGHT - MARGIN_HEIGHT*2;
				if(expand==true)
				{
					fromDisconnect.y= this.getHeight()/2 - fromDisconnect.height/2;
				}
				else
				{
					fromDisconnect.y= MARGIN_HEIGHT;
				}
				fromDisconnect.addEventListener(MouseEvent.CLICK,onRemoveDKRelation);
				
				fromDisconnectRelation= _DKRelation;
				showFromDisconnect=true;
			}
			else
			{
				this.removeChild(fromDisconnect);
				fromDisconnect=null;
				fromDisconnectRelation=null;
				showFromDisconnect=false;
			}
			this.invalidateDisplayList();
		}
		
		public function showToConnect(_KConRelation:KConRelationSkeleton, _isShow:Boolean):void
		{
			if(_isShow == true)
			{
				deriveDisconnect=new Button();
				this.addChild(deriveDisconnect);
				deriveDisconnect.label="";
				deriveDisconnect.x= getWidth();
				deriveDisconnect.width= BUTTON_WIDTH/2;
				deriveDisconnect.height= DEFAULT_MINI_HEIGHT - MARGIN_HEIGHT*2;
				if(expand==true)
				{
					deriveDisconnect.y= this.getHeight()/2 - deriveDisconnect.height/2;
				}
				else
				{
					deriveDisconnect.y= MARGIN_HEIGHT;
				}
				deriveDisconnect.addEventListener(MouseEvent.CLICK,onRemoveKConRelation);
				
				deriveDisconnectRelation=_KConRelation;
				showDeriveDisconnect=true;
			}
			else
			{
				this.removeChild(deriveDisconnect);
				deriveDisconnect=null;
				deriveDisconnectRelation=null;
				showDeriveDisconnect=false;
			}
			this.invalidateDisplayList();
		}
		
		private function onRemoveDKRelation(evt:MouseEvent):void
		{
			canvas.curProject.removeDK(fromDisconnectRelation,1);		
		}
		
		private function onRemoveKConRelation(evt:MouseEvent):void
		{
			canvas.curProject.removeKCon(deriveDisconnectRelation,0);
			
		}
		
		override protected function turnLife():void
		{
			var KConList:ArrayList= (KnowledgeSkeleton)(this.getSkeleton()).getKConList();
			if(KConList == null)
			{
				return;
			}
			var i:Number=0;
			for(i=0; i<KConList.length; i++)
			{
				var curKCon:KConRelationSkeleton = (KConRelationSkeleton)(KConList.getItemAt(i));
				var curCon:ConclustionSprite= (ConclustionSprite)(curKCon.getToPointSkeleton().getSprite());
				
				if(curKCon==null)
				{
					return;
				}
				
				if(curKCon.getType() == 0)
				{
					curCon.increaseLife();
				}
				else
				{
					curCon.increasePoison();
				}
			}
		}
		
		override protected function turnNoLife():void
		{
			var KConList:ArrayList= (KnowledgeSkeleton)(this.getSkeleton()).getKConList();
			if(KConList == null)
			{
				return;
			}
			var i:Number=0;
			for(i=0; i<KConList.length; i++)
			{
				var curKCon:KConRelationSkeleton = (KConRelationSkeleton)(KConList.getItemAt(i));
				var curCon:ConclustionSprite= (ConclustionSprite)(curKCon.getToPointSkeleton().getSprite());
				
				if(curKCon==null)
				{
					return;
				}
				
				if(curKCon.getType() == 0)
				{
					curCon.decreaseLife();
				}
				else
				{
					curCon.decreasePoison();
				}
			}
		}
		
		override protected function convertExpand():void
		{
			super.convertExpand();
			if(fromDisconnect!=null)
			{
				if(expand==true)
				{
					fromDisconnect.y= this.getHeight()/2 - fromDisconnect.height/2;
					
				}
				else
				{
					fromDisconnect.y= MARGIN_HEIGHT;
				}
			}
			if(deriveDisconnect!=null)
			{
				if(expand==true)
				{
					deriveDisconnect.y= this.getHeight()/2 - deriveDisconnect.height/2;
				}
				else
				{
					deriveDisconnect.y= MARGIN_HEIGHT;
				}
			}
		}
		
		override public function colorAfter():void
		{
			if(this.getLifeStatus() != 1)
				return;
			
			var KConList:ArrayList = (KnowledgeSkeleton)(getSkeleton()).getKConList();
			if(KConList==null)
				return;
			
			var i:int=0;
			for(i=0; i<KConList.length; i++)
			{
				var curKCon:KConRelationSkeleton = (KConRelationSkeleton)(KConList.getItemAt(i));
				if(curKCon.getType() == 0)
				{
					curKCon.getToPointSkeleton().getSprite().increaseLife();
				}
				else
				{
					curKCon.getToPointSkeleton().getSprite().increasePoison();	
				}
			}
		}
		
		override public function highlightAfter(_showDelButton:Boolean):void
		{
			var KConList:ArrayList = (KnowledgeSkeleton)(getSkeleton()).getKConList();
			if(KConList==null)
				return;
			
			var i:int=0;
			for(i=0; i<KConList.length; i++)
			{
				var curKCon:KConRelationSkeleton = (KConRelationSkeleton)(KConList.getItemAt(i));
				curKCon.getSprite().setSelected(true);
				
				curKCon.getToPointSkeleton().getSprite().setHighlight(true);
				if(_showDelButton==true)
				{
					curKCon.getToPointSkeleton().getSprite().showFromDelButton(curKCon);
				}
			}
		}
		
		override public function highlightBefore(_showDelButton:Boolean):void
		{
			var DKList:ArrayList = (KnowledgeSkeleton)(getSkeleton()).getDKList();
			if(DKList==null)
				return;
			
			var i:int=0;
			for(i=0; i<DKList.length; i++)
			{
				var curDK:DKRelationSkeleton = (DKRelationSkeleton)(DKList.getItemAt(i));
				curDK.getSprite().setSelected(true);
				curDK.getFromPointSkeleton().getSprite().setHighlight(true);
				if(_showDelButton==true)
				{
					curDK.getFromPointSkeleton().getSprite().showDeriveDelButton(curDK);
				}
			}
		}
		
		override public function showFromDelButton(_relation:LineSkeleton):void
		{
			fromDisconnect.visible=true;
			fromDisconnectRelation = (DKRelationSkeleton)(_relation);
		}
		
		override public function showDeriveDelButton(_relation:LineSkeleton):void
		{
			deriveDisconnect.visible=true;
			deriveDisconnectRelation = (KConRelationSkeleton)(_relation);
		}
		
		override public function resetHighlight():void
		{
			super.resetHighlight();
			fromDisconnect.visible=false;
			fromDisconnectRelation=null;
			deriveDisconnect.visible=false;
			deriveDisconnectRelation=null;
		}
		
		override protected function onChanged(evt:PropertyChangeEvent):void
		{
			canvas.curProject.modifyName(this.getSkeleton(),(String)(evt.newValue),2);
		}
		
		override protected function onDiscriptionChanged(evt:PropertyChangeEvent):void
		{
			canvas.curProject.modifyDiscription(this.getSkeleton(),(String)(evt.newValue),2);
		}
	}
}